import re
import json
import time

from django.template.context_processors import csrf
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render
from django.core.exceptions import ObjectDoesNotExist
import pdfplumber
from pytils.translit import slugify

from main.models import Book, Quote, Note, Group, Author


def get_book(request, slug):

    """ Получаем книгу """

    def _convert_to_desired_view(book, text):
        text = text.replace('\t', ' ')[::-1]
        current_page = ''
        text = re.sub('^\d{,5}?\n', '', text)
        return (text[::-1], current_page)

    def _get_authors_name(book):
        full_name = book.author.name.split()
        name = full_name[0][0] + '. '
        surname = full_name[1]
        return name + surname

    def _get_right_pages(request, book):
        current_page = int(request.GET.get('page'))
        total_pages = book.volume
        previous_page = current_page -1 if (current_page -1) >= 0 else False
        next_page = current_page + 1
        return {'current_page': current_page,
                'total_pages': total_pages,
                'next_page': next_page,
                'previous_page': previous_page,
                'background': book.background,}

    def _get_context(request, slug, book):
        page_number = int(request.GET.get('page'))
        pages = _get_right_pages(request, book)
        path_to_book = book.file.path
        authors_name = _get_authors_name(book)
        quotes = get_information_about_book(request, book.slug)
        context = {'page_number': page_number,
                   'author': book.author.name,
                   'title': book.title,
                   'book_slug': book.slug,
                   'is_favorites': book.is_favorites,
                   'bookmark': book.bookmark,
                   'csrf_token': str(csrf(request)['csrf_token']),
                   'quotes': quotes,
                   'author_slug': book.author.slug,
                   **pages}
        with pdfplumber.open(path_to_book) as file:
            page = file.pages[page_number]
            text, current_page = _convert_to_desired_view(book, page.extract_text())
            context['text'] = text

        return context

    
    def add_book_to_last_reed(request, book):
        if isinstance(request.session.get('last_read'), dict):
            if book.pk not in request.session['last_read'].values():
                request.session['last_read'][int(time.time())] = book.pk
        else:
            request.session['last_read'] = {}

        request.session.modified = True


    # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

    book = Book.objects.get(slug=slug)

    if request.GET.get('page'):
        template = 'main/contents_of_book.html'
        context = _get_context(request, slug, book)
        del context['background']
        add_book_to_last_reed(request, book)
        return (template, context)

    else:
        template = 'main/book_big.html'
        context = {'book': book}
        return (template, context)


def get_list_of_books(request):

    """ Получаем список книг в нужном виде """

    def get_title(book):
        modified_book = book[0].split()
        if len(book[0]) > 23: return book[0][:19] + '...'
        else: return book[0]

    def get_description(book):
        return ' '.join(book[1].split()[:25]) + '...'

    def get_image(book):
        return 'media/' + book[3]


    # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

    result = []
    
    if request.GET.get('favorites_books'):
        books = Book.objects.values_list('title', 'description', 'slug', 'image').filter(is_favorites=True)
    else:
        books = Book.objects.values_list('title', 'description', 'slug', 'image').all()

    for book in books:
        title = get_title(book)
        description = get_description(book)
        image = get_image(book)
        result.append({'title': title, 'description': description, 'slug': book[2], 'image': image})

    return result


def add_bookmark(request, book, action, page):

    """ Добавляем в закладку страницу """

    book_orm = Book.objects.get(slug=book)

    if action == 'add':
        book_orm.bookmark = page
        book_orm.save()
    elif action == 'remove':
        book_orm.bookmark = 0
        book_orm.save()


def add_last_page(request, book, page_number):

    book = Book.objects.get(slug=book)
    book.last_page = page_number
    book.save()


def get_information_about_book(request, slug):

    """ Получаем информацию о книге """

    book = Book.objects.get(slug=slug)
    context = {'last_page': book.last_page,
               'volume': book.volume,
               'favorites': book.is_favorites}
    return context


def action_favorites(book, action):

    """ Выполняем какое-то действие с закладкой """

    book = Book.objects.get(slug=book)

    if action == 'remove_favorites':
        book.is_favorites = False
    elif action == 'add_favorites':
        book.is_favorites = True

    book.save()


def get_information_about_quotes(request, book_slug):

    """ Получаем информацию о цитатах """

    result = {'csrf_token': str(csrf(request)['csrf_token'])}
    quotes = {}

    book = Book.objects.get(slug=book_slug)
    quotesORM = book.quote_set.values_list('content', 'color', 'page_number', 'pk').all()

    for number, quote in enumerate(quotesORM, 0):
        quotes[number] = {'content': quote[0], 'color': quote[1],
                          'page_number': quote[2], 'id': quote[3]}

    result['quotes'] = quotes

    return result


def action_quote(request, book_slug):

    """ Совершаем какое-то действие над цитатой из книги """

    def remove_quote(request, book_slug, quote_id):

        quote = Quote.objects.get(pk=quote_id, book__slug=book_slug)
        quote.delete()


    # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

    data = json.loads(request.body)

    if 'remove_quote_id' in data:
        remove_quote(request, book_slug, data['remove_quote_id'])

    else:
        book = Book.objects.get(slug=book_slug)
        quote = Quote.objects.create(content=data['quote'], book=book,
                                     color=data['color'], page_number=data['page_number'])

        if data['note']:
            Note.objects.create(text=data['note'], content_object=quote)


def get_information_about_note(request, book_slug):

    """ Получаем инфомрацию о примечание """

    if 'quote_id' in request.GET:

        token = str(csrf(request)['csrf_token'])
        quote_id = int(request.GET['quote_id'])
        note_text = Quote.objects.get(pk=quote_id).notes.last()

        if note_text: return JsonResponse({'note_text': note_text.text, 'token': token})
        else: return JsonResponse({'note_text': 'Примечание к этой цитате не добавлялось'})

    else:
        print('reques.get', request.GET)
        

def action_note(request, book_slug):

    if 'delete_note' in request.GET:
        quote_id = int(request.GET['delete_note'])
        quoteORM = Quote.objects.get(pk=quote_id).notes.last()
        if quoteORM: quoteORM.delete()
        return HttpResponse('')


def perform_action_on_book(request, book_slug):

    """ Выполняем какое-то действие над книгой """

    def make_book_read(book):

        """ Помечаем книгу прочитанной """

        book.is_read = True
        book.save()
        return HttpResponse('')

    def make_book_unread(book):
        """ Помечаем книгу непрочитанной """
        book.is_read = False
        book.save()
        return HttpResponse('')


    def make_book_urgent(book):
        """ Помечаем книгу неотложенной """
        book.is_defer = False
        book.save()
        return HttpResponse('')


    def make_book_defer(book):
        """ Помечаем книгу отложенной """
        book.is_defer = True
        book.save()
        return HttpResponse('')


    def delete_book(book):
        """ Удаляем книгу """
        book.delete()
        return HttpResponse('')

    def change_group_book(book, group_slug):
        """ Меняем группу книге """
        groupORM = Group.objects.get(slug=group_slug)
        book.group = groupORM
        book.save()
        return HttpResponse('')

    def change_title_of_book(book, new_name):
        """ Меняем название книги """
        book.title = new_name
        book.slug = slugify(book.title)
        book.save()
        return HttpResponse('')

    def change_description_of_book(book, new_description):
        """ Меняем описание книги """
        book.description = new_description
        book.save()
        return HttpResponse('')

    def change_author_of_book(book, author):
        """ Меняем автора книги """
        author = Author.objects.get(slug=author)
        book.author = author
        book.save()
        return HttpResponse('')

    def change_cover_of_book(request, book):
        """ Меняем обложку книги """
        image = request.FILES.getlist('file')[0]
        book.image = image
        book.save()
        return JsonResponse({'image_url': book.image.url})

    def change_background_image_of_book(request, book):
        """ Меняем фоновое изображение книги """
        background = request.FILES.getlist('file')[0]
        book.background = background
        book.save()
        return HttpResponse('')


    # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

    book = Book.objects.get(slug=book_slug)

    if 'change_cover' in request.GET:
        return change_cover_of_book(request, book)

    if 'change_background_image' in request.GET:
        return change_background_image_of_book(request, book)

    data = json.loads(request.body)

    if 'make_book_read' in data:
        return make_book_read(book)

    if 'make_book_unread' in data:
        return make_book_unread(book)

    if 'urgent' in data:
        return make_book_urgent(book)

    if 'deferred' in data:
        return make_book_defer(book)
    
    if 'delete_book' in data:
        return delete_book(book)

    if 'group_name' in data:
        return change_group_book(book, data['group_name'])

    if 'new_book_title' in data:
        return change_title_of_book(book, data['new_book_title'])

    if 'new_book_description' in data:
        return change_description_of_book(book, data['new_book_description'])

    if 'new_author_name' in data:
        return change_author_of_book(book, data['new_author_name'])


def get_default_group():
    return Group.objects.get(title='Не указано')


def get_right_data_for_home_page(request):
    if request.session.get('last_read'):
        result = []
        list_of_books_sorted = sorted(request.session['last_read'])
        list_of_books_values = request.session['last_read'].values()
        list_of_books_pk = request.session['last_read'].values()

        for book_number in list_of_books_sorted:
            try:
                book = Book.objects.get(pk=request.session['last_read'][book_number])
                result.append(book)
            except ObjectDoesNotExist:
                pass

        result.reverse()
        return render(request, 'main/home_page.html', {'books': result[:5], 'bla': 'skfdj'})
    else:
        print('Ничего такого нет')


def add_book(request):
    cover_book = request.FILES.getlist('image')[0]
    file_book = request.FILES.getlist('file')[0]
    background_book = request.FILES.getlist('background')[0]
    Book.objects.create(
        title=request.POST.get('title'),
        description=request.POST.get('description'),
        author=Author.objects.get(slug=request.POST.get('author')),
        group=Group.objects.get(slug=request.POST.get('group')),
        image=cover_book,
        file=file_book,
        background=background_book)
